#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fastapi import APIRouter, HTTPException, Query, Path, Body, Depends
from typing import Dict, List, Optional, Any
from pydantic import BaseModel
import time
import logging

from service import (
    ParkingService,
    ReservationService,
    VehicleService,
    IncomeService,
    PricingRuleService,
    DashboardService
)

# 配置日志记录
logger = logging.getLogger(__name__)

# API路由
router = APIRouter(prefix="/api/v1")

# API模型
class ReservationCreate(BaseModel):
    plate_number: str
    spot_number: str
    start_time: Optional[int] = None
    end_time: Optional[int] = None  # 新增预约结束时间

class PricingRuleCreate(BaseModel):
    name: str
    free_duration: int
    unit_duration: int
    unit_price: float
    is_active: Optional[bool] = False

class PricingRuleUpdate(BaseModel):
    name: Optional[str] = None
    free_duration: Optional[int] = None
    unit_duration: Optional[int] = None
    unit_price: Optional[float] = None
    is_active: Optional[bool] = None

class VehicleEntry(BaseModel):
    plate_number: str
    spot_number: str

class VehicleExit(BaseModel):
    plate_number: str

class PaymentCreate(BaseModel):
    record_id: int
    payment_method: str = "wechat"  # 默认微信支付

# 仪表盘API
@router.get("/dashboard")
def get_dashboard():
    """获取仪表盘数据"""
    return DashboardService.get_dashboard_data()

# 车位API
@router.get("/parking/spots")
def get_parking_spots():
    """获取所有车位信息"""
    return ParkingService.get_parking_spots()

@router.get("/parking/summary")
def get_parking_summary():
    """获取车位使用情况汇总"""
    return ParkingService.get_parking_summary()

# 用户APP专用接口 - 实时车位状态
@router.get("/app/parking/spots")
def get_app_parking_spots():
    """获取APP用户可见的车位信息"""
    spots = ParkingService.get_parking_spots()
    # 简化返回数据，只返回必要的信息
    result = []
    for spot in spots:
        result.append({
            "spot_number": spot["spot_number"],
            "status": spot["status"],
            "last_updated": spot["last_updated"]
        })
    return result

# 预约API
@router.post("/reservations")
def create_reservation(reservation: ReservationCreate):
    """创建预约"""
    start_time = reservation.start_time or int(time.time() * 1000)
    result = ReservationService.create_reservation(
        reservation.plate_number,
        reservation.spot_number,
        start_time,
        reservation.end_time  # 增加结束时间参数
    )
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    return result

# APP专用预约API
@router.post("/app/reservations")
def create_app_reservation(reservation: ReservationCreate):
    """APP用户创建预约"""
    # 打印请求信息
    logger.info(f"收到预约请求: 车牌={reservation.plate_number}, 车位={reservation.spot_number}")
    
    # 获取车位总体情况
    parking_summary = ParkingService.get_parking_summary()
    logger.info(f"当前车位情况: {parking_summary}")
    
    # 检查是否有空车位
    if parking_summary["free_spots"] <= 0:
        logger.warning("无空闲车位可用")
        raise HTTPException(status_code=400, detail="当前无空车位，无法预约")
    
    # 检查用户指定的车位是否可用
    if reservation.spot_number:
        spot = ParkingService.get_parking_spot_by_number(reservation.spot_number)
        if not spot or spot["status"] != "free":
            logger.warning(f"指定车位 {reservation.spot_number} 不可用，尝试自动分配")
            # 如果指定的车位不可用，但还有其他空车位，可以自动分配一个
            available_spots = ParkingService.get_available_parking_spots()
            if available_spots:
                original_spot = reservation.spot_number
                reservation.spot_number = available_spots[0]["spot_number"]
                logger.info(f"自动分配车位: 从 {original_spot} 改为 {reservation.spot_number}")
            else:
                logger.error("无可用车位进行自动分配")
                raise HTTPException(status_code=400, detail="指定车位不可用，且无其他空车位")
        else:
            logger.info(f"指定车位 {reservation.spot_number} 可用")
    else:
        # 如果没有指定车位，则自动分配一个
        logger.info("未指定车位，进行自动分配")
        available_spots = ParkingService.get_available_parking_spots()
        if available_spots:
            reservation.spot_number = available_spots[0]["spot_number"]
            logger.info(f"自动分配车位: {reservation.spot_number}")
        else:
            # 这种情况理论上不会发生，因为前面已经检查了free_spots
            logger.error("无可用车位进行自动分配")
            raise HTTPException(status_code=400, detail="无可用车位")
    
    # 创建预约
    start_time = reservation.start_time or int(time.time() * 1000)
    result = ReservationService.create_reservation(
        reservation.plate_number,
        reservation.spot_number,
        start_time,
        reservation.end_time
    )
    
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    
    return {
        "success": True,
        "reservation_id": result["reservation_id"],
        "message": "预约成功",
        "details": {
            "plate_number": reservation.plate_number,
            "spot_number": reservation.spot_number,
            "start_time": start_time,
            "end_time": reservation.end_time
        }
    }

@router.get("/reservations")
def get_reservations(status: Optional[str] = None):
    """获取预约列表"""
    return ReservationService.get_reservations(status)

# APP用户查询预约
@router.get("/app/reservations/plate/{plate_number}")
def get_reservations_by_plate(plate_number: str):
    """根据车牌号查询预约"""
    reservations = ReservationService.get_reservations_by_plate(plate_number)
    if not reservations:
        return {"reservations": [], "message": "没有找到相关预约"}
    return {"reservations": reservations}

@router.get("/reservations/{reservation_id}")
def get_reservation(reservation_id: int = Path(..., title="预约ID")):
    """获取特定预约"""
    reservation = ReservationService.get_reservation(reservation_id)
    if not reservation:
        raise HTTPException(status_code=404, detail="预约不存在")
    return reservation

@router.post("/reservations/{reservation_id}/cancel")
def cancel_reservation(reservation_id: int = Path(..., title="预约ID")):
    """取消预约"""
    result = ReservationService.cancel_reservation(reservation_id)
    if not result.get("success", False):
        raise HTTPException(status_code=400, detail=result.get("message", "取消预约失败"))
    return result

# APP用户取消预约
@router.post("/app/reservations/{reservation_id}/cancel")
def app_cancel_reservation(reservation_id: int = Path(..., title="预约ID")):
    """APP用户取消预约"""
    # 直接调用取消预约方法，该方法内部会进行状态验证
    result = ReservationService.cancel_reservation(reservation_id)
    if not result.get("success", False):
        raise HTTPException(status_code=400, detail=result.get("message", "取消预约失败"))
    return result

# 车辆API
@router.post("/vehicles/entry")
def process_vehicle_entry(entry: VehicleEntry):
    """处理车辆进入"""
    result = VehicleService.process_vehicle_entry(entry.plate_number, entry.spot_number)
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    return result

@router.post("/vehicles/exit")
def process_vehicle_exit(exit: VehicleExit):
    """处理车辆离开"""
    result = VehicleService.process_vehicle_exit(exit.plate_number)
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    return result

@router.get("/vehicles/records")
def get_vehicle_records():
    """获取车辆记录"""
    return VehicleService.get_vehicle_records()

# APP用户查询当前停车状态
@router.get("/app/vehicles/current/{plate_number}")
def get_current_parking_status(plate_number: str):
    """APP用户查询当前停车状态和计费"""
    # 查询当前活跃的车辆记录
    record = VehicleService.get_active_vehicle_record(plate_number)
    if not record:
        return {
            "parking": False,
            "message": "当前没有停车记录"
        }
    
    # 计算当前时长和费用
    current_time = int(time.time() * 1000)
    duration_ms = current_time - record["entry_time"]
    duration_minutes = int(duration_ms / 60000)  # 转换为分钟
    
    # 获取计费规则
    rule = PricingRuleService.get_active_pricing_rule()
    
    # 计算费用
    free_minutes = int(rule["free_duration"] / 60000)  # 转换为分钟
    if duration_minutes <= free_minutes:
        fee = 0
    else:
        # 计算超出免费时段的时间
        chargeable_minutes = duration_minutes - free_minutes
        # 计算收费单元数量
        unit_minutes = int(rule["unit_duration"] / 60000)  # 转换为分钟
        units = (chargeable_minutes + unit_minutes - 1) // unit_minutes  # 向上取整
        fee = units * rule["unit_price"]
    
    return {
        "parking": True,
        "record_id": record["id"],
        "plate_number": plate_number,
        "spot_number": record["spot_number"],
        "entry_time": record["entry_time"],
        "current_time": current_time,
        "duration_minutes": duration_minutes,
        "fee": fee,
        "fee_rule": {
            "name": rule["name"],
            "free_minutes": free_minutes,
            "unit_minutes": int(rule["unit_duration"] / 60000),
            "unit_price": rule["unit_price"]
        }
    }

# 收入API
@router.get("/income/records")
def get_income_records():
    """获取收入记录"""
    return IncomeService.get_income_records()

@router.get("/income/total")
def get_total_income():
    """获取总收入"""
    return {"total": IncomeService.get_total_income()}

@router.get("/income/unpaid")
def get_unpaid_bills():
    """获取所有未支付账单"""
    logger.info(f"获取所有未支付账单")
    bills = IncomeService.get_all_unpaid_bills()
    
    # 添加详细日志
    logger.info(f"获取到 {len(bills)} 条未支付账单")
    for bill in bills:
        logger.info(f"账单: ID={bill['id']}, 车牌={bill['plate_number']}, 车位={bill.get('spot_number', '未知')}, 金额={bill['amount']}")
        
        # 确保账单数据包含前端所需的所有字段
        if 'spot_number' not in bill or not bill['spot_number']:
            bill['spot_number'] = "未知"
    
    return bills

@router.post("/income/bills/{record_id}/pay")
def pay_income_bill(record_id: int):
    """前端支付账单"""
    # 获取收入记录
    bill = IncomeService.get_income_record(record_id)
    if not bill:
        raise HTTPException(status_code=404, detail="账单不存在")
    
    if bill.get("paid", False):
        raise HTTPException(status_code=400, detail="该账单已支付")
    
    # 处理支付
    result = IncomeService.process_payment(record_id, "web")
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    
    return {
        "success": True,
        "message": "支付成功",
        "payment_id": result["payment_id"],
        "payment_time": result["payment_time"]
    }

# APP用户查询账单
@router.get("/app/bills/{plate_number}")
def get_user_bills(plate_number: str):
    """获取用户账单"""
    # 获取未支付的收入记录
    bills = IncomeService.get_unpaid_bills(plate_number)
    if not bills:
        return {"bills": [], "message": "没有未支付的账单"}
    
    return {"bills": bills}

# APP用户支付账单
@router.post("/app/bills/{record_id}/pay")
def pay_bill(record_id: int, payment: PaymentCreate):
    """支付账单"""
    # 获取收入记录
    bill = IncomeService.get_income_record(record_id)
    if not bill:
        raise HTTPException(status_code=404, detail="账单不存在")
    
    if bill.get("paid", False):
        raise HTTPException(status_code=400, detail="该账单已支付")
    
    # 模拟支付过程
    result = IncomeService.process_payment(record_id, payment.payment_method)
    if not result["success"]:
        raise HTTPException(status_code=400, detail=result["message"])
    
    return {
        "success": True,
        "message": "支付成功",
        "payment_id": result["payment_id"],
        "payment_time": result["payment_time"]
    }

# 计费规则API
@router.get("/pricing/rules")
def get_pricing_rules():
    """获取所有计费规则"""
    return PricingRuleService.get_pricing_rules()

@router.get("/pricing/rules/active")
def get_active_pricing_rule():
    """获取活跃的计费规则"""
    rule = PricingRuleService.get_active_pricing_rule()
    if not rule:
        raise HTTPException(status_code=404, detail="未找到活跃的计费规则")
    return rule

@router.post("/pricing/rules")
def create_pricing_rule(rule: PricingRuleCreate):
    """创建计费规则"""
    rule_id = PricingRuleService.create_pricing_rule(
        rule.name,
        rule.free_duration,
        rule.unit_duration,
        rule.unit_price,
        rule.is_active
    )
    if not rule_id:
        raise HTTPException(status_code=400, detail="创建计费规则失败")
    return {"id": rule_id, "success": True}

@router.put("/pricing/rules/{rule_id}")
def update_pricing_rule(rule_id: int, rule: PricingRuleUpdate):
    """更新计费规则"""
    current_rule = PricingRuleService.get_active_pricing_rule()
    if not current_rule:
        raise HTTPException(status_code=404, detail="计费规则不存在")
    
    name = rule.name if rule.name is not None else current_rule["name"]
    free_duration = rule.free_duration if rule.free_duration is not None else current_rule["free_duration"]
    unit_duration = rule.unit_duration if rule.unit_duration is not None else current_rule["unit_duration"]
    unit_price = rule.unit_price if rule.unit_price is not None else current_rule["unit_price"]
    is_active = rule.is_active if rule.is_active is not None else current_rule["is_active"]
    
    result = PricingRuleService.update_pricing_rule(
        rule_id,
        name,
        free_duration,
        unit_duration,
        unit_price,
        is_active
    )
    
    if not result:
        raise HTTPException(status_code=400, detail="更新计费规则失败")
    return {"success": True}

@router.post("/pricing/rules/{rule_id}/activate")
def activate_pricing_rule(rule_id: int):
    """激活计费规则"""
    result = PricingRuleService.activate_pricing_rule(rule_id)
    if not result:
        raise HTTPException(status_code=400, detail="激活计费规则失败")
    return {"success": True}

@router.post("/debug/mqtt-simulate")
def simulate_mqtt_message(
    plate_number: str = Body(..., embed=True, description="车牌号码"),
    timestamp: Optional[int] = Body(None, embed=True, description="时间戳(毫秒)")
):
    """
    模拟MQTT消息，用于测试车牌识别流程
    """
    import hashlib
    import asyncio
    from main import on_message
    
    # 创建模拟消息内容
    current_time = timestamp or int(time.time() * 1000)
    
    # 构造模拟的MQTT消息负载
    payload = {
        "items": {
            "Car_number": {
                "value": plate_number,
                "time": current_time
            }
        }
    }
    
    # 创建模拟的MQTT消息对象
    class MockMsg:
        def __init__(self, topic, payload):
            self.topic = topic
            self.payload = payload
        
        def decode(self):
            return self.payload
    
    # 序列化为JSON字符串
    import json
    payload_json = json.dumps(payload)
    mqtt_topic = "/sys/k1i7vknfFR7/android_app/thing/service/property/set"
    
    # 创建模拟消息对象
    mock_msg = MockMsg(mqtt_topic, payload_json.encode())
    
    # 调用MQTT消息处理函数
    try:
        on_message(None, None, mock_msg)
        return {
            "success": True, 
            "message": f"已模拟车牌 {plate_number} 的MQTT消息", 
            "time": current_time
        }
    except Exception as e:
        logger.error(f"模拟MQTT消息异常: {e}")
        logger.exception(e)
        raise HTTPException(status_code=500, detail=f"模拟MQTT消息失败: {str(e)}") 